/*
 * Copyright (c) 2009. Silenus Consultoria, S.L.
 */
package es.silenus.detecta.controller;

import es.silenus.detecta.Constants;

import es.silenus.detecta.dao.KnowledgeUnitDAO;
import es.silenus.detecta.dao.Page;
import es.silenus.detecta.dao.TrainingActionDAO;

import es.silenus.detecta.model.KnowledgeUnit;
import es.silenus.detecta.model.TrainingAction;
import es.silenus.detecta.model.User;

import org.apache.commons.lang.CharUtils;
import org.apache.commons.lang.StringUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.web.bind.ServletRequestUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * DOCUMENT ME!
 *
 * @author <a href="mailto:dgarcia@silenus-consultoria.es">Daniel García</a>
 *
 * @since 07-abr-2009 16:35:44
 */
public class TrainingController extends BaseController {
	/**
	 * Logger for this class.
	 */
	private static final Log LOG = LogFactory.getLog(TrainingController.class);

	/**
	 * Training Actions DAO
	 */
	private TrainingActionDAO trainingDAO;

	/**
	 * The knowledge unit DAO.
	 */
	private KnowledgeUnitDAO knowledgeUnitDAO;

	/**
	 * Sets the training DAO.
	 *
	 * @param trainingDAO the training DAO.
	 */
	public void setTrainingDAO(TrainingActionDAO trainingDAO) {
		this.trainingDAO = trainingDAO;
	}

	/**
	 * Sets the knowledge unit DAO.
	 *
	 * @param knowledgeUnitDAO the knowledgeUnit DAO.
	 */
	public void setKnowledgeUnitDAO(final KnowledgeUnitDAO knowledgeUnitDAO) {
		this.knowledgeUnitDAO = knowledgeUnitDAO;
	}

	/**
	 * Updates a training or creates a new one.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String updateTraining(HttpServletRequest request, HttpServletResponse response) {
		final User current = this.getUser(request);

		String id = request.getParameter("id");

		int trainingId = (id != null) ? Integer.parseInt(id) : 0;

		TrainingAction training;

		if(trainingId > 0) {
			training = trainingDAO.findById(trainingId);
		} else {
			training = new TrainingAction();
		}

		training.setOrganization(current.getOrganization());

		String temp = request.getParameter("code");

		if(temp != null) {
			training.setCode(temp);

			TrainingAction otherTraining = trainingDAO.findByCode(temp, current.getOrganization().getId());

			if((otherTraining != null) && (otherTraining.getId() != trainingId)) {
				request.setAttribute(Constants.ERRORS, "training.code.duplicated");

				return "secure/organization/training-update-error";
			}
		}

		temp = request.getParameter("name");

		if(temp != null) {
			training.setName(temp);
		}

		temp = request.getParameter("description");

		if(temp != null) {
			training.setDescription(temp);
		}

		if(trainingId > 0) {
			trainingDAO.update(training);
		} else {
			trainingDAO.save(training);
		}

		return "secure/organization/training-updated";
	}

	/**
	 * Finds trainings.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String findTraining(final HttpServletRequest request, final HttpServletResponse response) {
		final User current = getUser(request);

		Map<String, Object> sample = new HashMap<String, Object>();
		String temp = request.getParameter("id");

		if(temp != null) {
			sample.put("id", temp);
		}

		temp = request.getParameter("code");

		if(temp != null) {
			sample.put("code", temp);
		}

		temp = request.getParameter("name");

		if(temp != null) {
			temp = StringUtils.replaceChars(temp, CharUtils.CR, ' ');
			temp = StringUtils.replaceChars(temp, CharUtils.LF, ' ');
			sample.put("name", temp);
		}

		temp = request.getParameter("description");

		if(temp != null) {
			temp = StringUtils.replaceChars(temp, CharUtils.CR, ' ');
			temp = StringUtils.replaceChars(temp, CharUtils.LF, ' ');
			sample.put("description", temp);
		}

		sample.put("organization.id", current.getOrganization().getId());

		int start = Integer.parseInt(request.getParameter("start"));
		int limit = Integer.parseInt(request.getParameter("limit"));
		String[] sortFields = request.getParameterValues("sort");
		String[] sortDirections = request.getParameterValues("dir");

		Page<TrainingAction> page = trainingDAO.findByExample(sample, start, limit, sortFields, sortDirections);

		request.setAttribute("page", page);

		return "secure/organization/training-search";
	}

	/**
	 * Retrieves the trainings.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String getTrainings(final HttpServletRequest request, final HttpServletResponse response) {
		User current = getUser(request);
		int organizationId = ServletRequestUtils.getIntParameter(request, "organization", -1);

		if(current != null) {
			organizationId = current.getOrganization().getId();
		}

		String query = request.getParameter("query");

		List<TrainingAction> result;

		if((query != null) && (query.length() > 0)) {
			Map<String, Object> sample = new HashMap<String, Object>();

			// sample.put("code", query);
			sample.put("name", query);
			sample.put("organization.id", organizationId);

			result = trainingDAO.findByExample(sample);
		} else {
			result = trainingDAO.findByOrganization(organizationId);
		}

		request.setAttribute("result", result);

		return "secure/organization/trainings";
	}

	/**
	 * Find associated units.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String findAssociatedUnits(final HttpServletRequest request, final HttpServletResponse response) {
		int id = Integer.parseInt(request.getParameter("id"));

		Map<String, Object> sample = new HashMap<String, Object>();

		sample.put("id", id);

		int start = Integer.parseInt(request.getParameter("start"));
		int limit = Integer.parseInt(request.getParameter("limit"));
		String[] sortFields = request.getParameterValues("sort");
		String[] sortDirections = request.getParameterValues("dir");


		Page<KnowledgeUnit> page = trainingDAO.findAssociatedUnits(sample, start, limit, sortFields, sortDirections);

		request.setAttribute("page", page);

		return "secure/organization/units";
	}

	/**
	 * Find non-associated units.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String findNonAssociatedUnits(final HttpServletRequest request, final HttpServletResponse response) {
		int id = Integer.parseInt(request.getParameter("id"));

		Map<String, Object> sample = new HashMap<String, Object>();

		sample.put("id", id);

		int start = Integer.parseInt(request.getParameter("start"));
		int limit = Integer.parseInt(request.getParameter("limit"));
		String[] sortFields = request.getParameterValues("sort");
		String[] sortDirections = request.getParameterValues("dir");


		Page<KnowledgeUnit> page = trainingDAO.findNonAssociatedUnits(sample, start, limit, sortFields, sortDirections);

		request.setAttribute("page", page);

		return "secure/organization/units";
	}

	/**
	 * Adds a unit.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String addUnit(final HttpServletRequest request, final HttpServletResponse response) {
		int id = Integer.parseInt(request.getParameter("id"));
		String[] units = request.getParameterValues("units");

		if(units != null) {
			Long[] unitIds = new Long[units.length];

			for(int i = 0; i < units.length; ++i) {
				unitIds[i] = Long.parseLong(units[i]);
			}

			TrainingAction training = trainingDAO.findById(id);
			List<KnowledgeUnit> theUnits = knowledgeUnitDAO.findByIds(unitIds);

			training.getUnits().addAll(theUnits);
			trainingDAO.update(training);
		}

		return "secure/organization/unit-added";
	}

	/**
	 * Removes a unit.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String removeUnit(final HttpServletRequest request, final HttpServletResponse response) {
		int id = Integer.parseInt(request.getParameter("id"));
		String[] units = request.getParameterValues("units");

		if(units != null) {
			Long[] unitIds = new Long[units.length];

			for(int i = 0; i < units.length; ++i) {
				unitIds[i] = Long.parseLong(units[i]);
			}

			TrainingAction training = trainingDAO.findById(id);
			List<KnowledgeUnit> theUnits = knowledgeUnitDAO.findByIds(unitIds);

			training.getUnits().removeAll(theUnits);
			trainingDAO.update(training);
		}

		return "secure/organization/unit-removed";
	}

	/**
	 * Checks remove training actions.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String checkDeleteTrainings(final HttpServletRequest request, final HttpServletResponse response) {
		String[] trainings = request.getParameterValues("elements");

		if(trainings != null) {
			Integer[] trainingIds = new Integer[trainings.length];

			for(int i = 0; i < trainings.length; ++i) {
				trainingIds[i] = Integer.parseInt(trainings[i]);
			}

			List theTrainings = trainingDAO.getRemovalInformation(trainingIds);

			request.setAttribute("trainings", theTrainings);
		}

		return "secure/organization/trainings-check-removed";
	}

	/**
	 * Remove training actions.
	 *
	 * @param request the request.
	 * @param response the response.
	 *
	 * @return the view name.
	 */
	public String deleteTrainings(final HttpServletRequest request, final HttpServletResponse response) {
		String[] trainings = request.getParameterValues("elements");

		if(trainings != null) {
			Integer[] trainingIds = new Integer[trainings.length];

			for(int i = 0; i < trainings.length; ++i) {
				trainingIds[i] = Integer.parseInt(trainings[i]);
			}

			trainingDAO.remove(trainingIds);
		}

		return "secure/organization/trainings-removed";
	}
}
